/**
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import { DataGridColumn, DataGridProps } from '../data-grid.props';
import { computed, Ref, ref } from 'vue';
import { UseFitColumn, UseResize, UseVirtualScroll } from './types';
import { ColumnRenderContext } from './use-column';

export function useResize(
    props: DataGridProps,
    context: Ref<ColumnRenderContext>,
    useFitColumnComposition: UseFitColumn,
    useVirtualScrollComposition: UseVirtualScroll
): UseResize {
    const resizeBarPosition = ref(-1);
    const resizeHandleOffset = ref(0);
    const showColumnResizeHandle = ref(false);
    let columnField = '';

    const resizeHandleStyle = computed(() => {
        const styleObject = {
            display: showColumnResizeHandle.value ? 'block' : 'none',
            left: `${resizeHandleOffset.value}px`
        } as Record<string, any>;
        return styleObject;
    });

    const resizeOverlayStyle = computed(() => {
        const styleObject = {
            display: showColumnResizeHandle.value ? 'block' : 'none'
        } as Record<string, any>;
        return styleObject;
    });

    function draggingResizeHandle($event: MouseEvent) {
        const { left: dataGridOffsetLeft } = ((($event as any).target.parentElement as HTMLElement).getBoundingClientRect() as DOMRect);
        resizeHandleOffset.value = $event.clientX - dataGridOffsetLeft;
    }

    function releaseMouseMove($event: MouseEvent) {
        const column =
            context.value.primaryColumns.filter((column: DataGridColumn) => column.visible)
                .find((column: DataGridColumn) => column.field === columnField) ||
            context.value.leftColumns.filter((column: DataGridColumn) => column.visible)
                .find((column: DataGridColumn) => column.field === columnField) ||
            context.value.rightColumns.filter((column: DataGridColumn) => column.visible)
                .find((column: DataGridColumn) => column.field === columnField);
        if (column) {
            const { left: dataGridOffsetLeft } = ((($event as any).target.parentElement as HTMLElement).getBoundingClientRect() as DOMRect);
            const mouseReleasePosition = $event.clientX - dataGridOffsetLeft;
            column.actualWidth = (column.actualWidth || 0) + (mouseReleasePosition - resizeBarPosition.value);
            useFitColumnComposition.calculateColumnHeaders(context);
            useFitColumnComposition.calculateColumnsWidth(context);
        }
        resizeHandleOffset.value = 0;
        showColumnResizeHandle.value = false;
        useVirtualScrollComposition.reCalculateVisualDataRows();
        document.removeEventListener('mousemove', draggingResizeHandle);
        document.body.style.userSelect = '';
        columnField = '';
    }

    function onClickColumnResizeBar($event: MouseEvent, columnFieldName: string) {
        columnField = columnFieldName;
        showColumnResizeHandle.value = true;
        const clickElementPath = $event.composedPath();
        const gridElement = clickElementPath.find((element: any) => element.className.split(' ')[0] === 'fv-grid');
        if (gridElement) {
            const { left: dataGridOffsetLeft } = ((gridElement as HTMLElement).getBoundingClientRect() as DOMRect);
            resizeHandleOffset.value = $event.clientX - dataGridOffsetLeft;
            resizeBarPosition.value = $event.clientX - dataGridOffsetLeft;
            document.addEventListener('mousemove', draggingResizeHandle);
            document.addEventListener('mouseup', releaseMouseMove);
            document.body.style.userSelect = 'none';
        }
    }

    return { onClickColumnResizeBar, resizeHandleStyle, resizeOverlayStyle };
}
